<script setup lang="ts">
  import { useTypingStore } from '@renderer/store'
  import { ref, onMounted, nextTick, watch } from 'vue'

  const typingStore = useTypingStore()

  // 状态变量
  const inputRef = ref<HTMLInputElement | null>(null)
  const sentenceRef = ref<HTMLElement | null>(null)
  const ignoreNextInput = ref(false)

  // 处理输入
  const handleInput = (e: Event) => {
    if (ignoreNextInput.value) {
      ignoreNextInput.value = false
      return
    }

    typingStore.startTimer()

    const input = e.target as HTMLInputElement
    const newValue = input.value

    typingStore.inputs[typingStore.currentIndex] = newValue
    typingStore.totalTypedChars = typingStore.inputs.reduce((sum, input) => sum + input.length, 0)

    // 计算当前输入的错误数
    const currentSentence = typingStore.sentences[typingStore.currentIndex]
    let errorCount = 0
    for (let i = 0; i < newValue.length; i++) {
      if (i >= currentSentence.length || newValue[i] !== currentSentence[i]) {
        errorCount++
      }
    }
    typingStore.totalErrorChars = errorCount
  }

  // 处理按键
  const handleKeyDown = (e: KeyboardEvent) => {
    if (typingStore.isPaused) {
      e.preventDefault()
      return
    }

    if (e.key === 'Enter') {
      e.preventDefault()

      // 在输入完成时检查错误
      const currentInput = typingStore.inputs[typingStore.currentIndex]
      const currentSentence = typingStore.sentences[typingStore.currentIndex]

      // 计算最终错误数
      let errorCount = 0
      for (let i = 0; i < Math.max(currentInput.length, currentSentence.length); i++) {
        if (
          i >= currentInput.length ||
          i >= currentSentence.length ||
          currentInput[i] !== currentSentence[i]
        ) {
          errorCount++
        }
      }
      typingStore.totalErrorChars = errorCount
      typingStore.totalErrorCount++

      if (
        typingStore.currentIndex < typingStore.sentences.length - 1 &&
        typingStore.inputs[typingStore.currentIndex].length > 0
      ) {
        typingStore.currentIndex++
      } else if (typingStore.currentIndex === typingStore.sentences.length - 1) {
        typingStore.completed()
      }
    } else if (e.key === 'Backspace') {
      if (
        typingStore.inputs[typingStore.currentIndex].length === 0 &&
        typingStore.currentIndex > 0
      ) {
        typingStore.currentIndex--
        e.preventDefault()
      }
    }
  }

  // 获取字符样式
  const getCharClass = (charIndex: number) => {
    const input = typingStore.inputs[typingStore.currentIndex]
    const sentence = typingStore.sentences[typingStore.currentIndex]
    const sentenceLength = sentence.length

    if (charIndex < input.length) {
      if (charIndex >= sentenceLength) {
        return 'text-red-400'
      }
      return input[charIndex] === sentence[charIndex]
        ? 'dark:text-white text-black'
        : 'text-red-400'
    }

    return 'text-gray-400'
  }

  // 获取需要显示的字符
  const getDisplayChar = (charIndex: number) => {
    const sentence = typingStore.sentences[typingStore.currentIndex]
    const input = typingStore.inputs[typingStore.currentIndex] || ''
    const sentenceLength = sentence.length

    if (charIndex < sentenceLength) {
      return sentence[charIndex]
    } else if (charIndex >= sentenceLength && charIndex < input.length) {
      return input[charIndex]
    }

    return ''
  }

  // 获取要显示的字符数组
  const getDisplayChars = () => {
    const sentence = typingStore.sentences[typingStore.currentIndex]
    if (!sentence) return
    const input = typingStore.inputs[typingStore.currentIndex] || ''
    const displayLength = Math.max(sentence.length, input.length)
    return Array.from({ length: displayLength }, (_, i) => i)
  }

  // 聚焦输入框
  const focusInput = () => {
    nextTick(() => {
      if (inputRef.value) {
        inputRef.value.focus()
      }
    })
  }

  // 设置引用
  const setInputRef = (el: HTMLInputElement) => {
    if (el) {
      inputRef.value = el
    }
  }

  // 设置句子元素引用
  const setSentenceRef = (el: HTMLElement) => {
    if (el) {
      sentenceRef.value = el
    }
  }

  // 监听当前索引变化
  watch(
    () => typingStore.currentIndex,
    () => {
      nextTick(() => {
        focusInput()
      })
    }
  )

  // 向外暴露方法
  const focusCurrentInput = () => {
    focusInput()
  }

  defineExpose({
    focusCurrentInput
  })

  onMounted(() => {
    nextTick(() => {
      focusInput()
    })
  })
</script>

<template>
  <div class="flex flex-col gap-4 items-center">
    <!-- 显示当前句子 -->
    <div
      class="inline-flex flex-col items-center relative"
      :ref="(el) => setSentenceRef(el as HTMLElement)"
    >
      <div class="flex flex-row relative">
        <span
          v-for="(_char, charIndex) in getDisplayChars()"
          :key="charIndex"
          class="text-2xl font-semibold font-mono"
          :class="getCharClass(charIndex)"
        >
          {{ getDisplayChar(charIndex) }}
        </span>
      </div>
      <!-- 输入框 -->
      <input
        :ref="(el) => setInputRef(el as HTMLInputElement)"
        type="text"
        class="outline-none text-2xl text-white font-semibold tracking-normal font-mono border-b-2 border-indigo-400 bg-transparent h-12 w-full whitespace-pre"
        :value="typingStore.inputs[typingStore.currentIndex] || ''"
        @input="handleInput"
        @keydown="handleKeyDown"
      />
    </div>

    <!-- 显示下一个句子 -->
    <div
      v-if="typingStore.currentIndex < typingStore.sentences.length - 1"
      class="text-xl text-gray-400 flex flex-row items-center justify-center"
    >
      <i class="i-fa6-solid-arrow-right-long text-sm"></i>
      {{ typingStore.sentences[typingStore.currentIndex + 1] }}
    </div>
  </div>
</template>

<style lang="scss" scoped></style>
